package com.gavin.plugin.database.help;

import java.sql.SQLException;
import java.util.Random;

import com.gavin.model.JObject;
import com.gavin.model.Model;
import com.gavin.plugin.database.ext.MathExt;
import com.gavin.schema.dataservice.BigTable;

/**
 * ------------------------------
 * 分片工具类
 * ------------------------------
 * @author wdm（l311576@sina.com）  @date 2018年9月16日
 * @version 1.0
 */
public class ShardingUtils {
	public static Random rand = new Random();

	public static  int selectDatabase(BigTable bigTable,Model modelRequest, String strBigTableName, String strIdParaName) throws SQLException {
//		BigTable bigTable = this.getBigTable(strBigTableName);
		if (bigTable == null) {
			throw new SQLException("Dest-table not found: " + strBigTableName);
		}

		long lId = getKeyIdValue(strIdParaName, modelRequest, bigTable.getHashedIdCount());

		return (int) ((lId / bigTable.getGroupTableCapacity()) / bigTable.getGroupTableCount());
	}
	
	public static int selectTable(BigTable bigTable,Model modelRequest, String strBigTableName, String strIdParaName) throws SQLException {
//		BigTable bigTable = this.getBigTable(strBigTableName);
		if (bigTable == null) {
			throw new SQLException("Dest-table not found: " + strBigTableName);
		}

		long lId = getKeyIdValue(strIdParaName, modelRequest, bigTable.getHashedIdCount());

		return (int) ((lId / bigTable.getGroupTableCapacity()));
	}
	
	public static long getKeyIdValue(String strIdText, Model model, int nHashedIdCount) {
		return getShardingId(strIdText,  model,  nHashedIdCount);
	}
	
	public static long getShardingId(String strIdText, Model model, int nHashedIdCount) {
		long lValue = 0;
		JObject objIdValue = null;

		try {
			objIdValue = model.getJObject(strIdText);
		} catch (Exception e) {// Math
			lValue = MathExt.getMathValue(strIdText, model);

			return lValue;
		}

		// FieldId
		switch (objIdValue.getType()) {
		case _byte: {
			return (Byte) objIdValue.getValue();
		}
		case _short: {
			return (Short) objIdValue.getValue();
		}
		case _int: {
			return (Integer) objIdValue.getValue();
		}
		case _long: {
			return (Long) objIdValue.getValue();
		}
		case _string: {
			return Math.abs(((String) objIdValue.getValue()).toLowerCase().hashCode() % nHashedIdCount);
		}
		default: {
			throw new RuntimeException("Invalid type of KeyIdText " + strIdText);
		}
		}
	}
}
